package bjut.core.property;

import bjut.core.bean.BeanDefinition;
import bjut.core.exception.BeansException;
import bjut.core.factory.ConfigurableListableBeanFactory;
import bjut.core.postprocessor.BeanFactoryPostProcessor;
import bjut.core.resolver.StringValueResolver;
import bjut.core.resource.DefaultResourceLoader;
import bjut.core.resource.Resource;

import java.io.IOException;
import java.util.Properties;

/**
 * @Author: zhuzhiming
 * @Date: 2022/6/13 18:23
 */
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {


    private String location;

    public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

    public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            for (String beanName : beanDefinitionNames) {

                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) {
                        continue;
                    }
                    String strVal = (String) value;
                    value = resolvePlaceholder(strVal, properties);
                    propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), value));
                }
            }

            PlaceholderResolvingStringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(properties);
            beanFactory.addEmbeddedValueResolver(valueResolver);


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String resolvePlaceholder(String strVal, Properties properties) {
        StringBuilder sb = new StringBuilder(strVal);
        int startIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
        int stopIndex = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
        if (startIndex != -1 && stopIndex != -1 && startIndex < stopIndex) {
            String proKey = strVal.substring(startIndex + 2, stopIndex);
            String proVal = properties.getProperty(proKey);
            sb.replace(startIndex, stopIndex, proVal);
        }
        return sb.toString();
    }

    private class PlaceholderResolvingStringValueResolver implements StringValueResolver {

        private final Properties properties;

        public PlaceholderResolvingStringValueResolver(Properties properties) {
            this.properties = properties;
        }

        @Override
        public String resolverStringValue(String strVal) {
            return PropertyPlaceholderConfigurer.this.resolvePlaceholder(strVal, properties);
        }
    }


    public void setLocation(String location) {
        this.location = location;
    }

}
